# -*- coding: utf-8 -*-
'''
Created on 2011-8-8

@author: jiz
'''
from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp.util import login_required
from google.appengine.api import users
import urllib
import httplib
import datetime
from django.utils import simplejson as json
import logging

client_id = '227065848161.apps.googleusercontent.com'
client_secret = '0MbmeRcrk6xqLbyKMgNSZTFS'
scope = 'https://www.google.com/m8/feeds/'
redirect_uri = 'http://contactsbirthday.appspot.com/oauthtoken'
#redirect_uri = 'http://localhost:8080/oauthtoken'
code_uri = 'https://accounts.google.com/o/oauth2/auth'
token_uri = 'https://accounts.google.com/o/oauth2/token'

class Credentials(db.Model):
    user = db.UserProperty()
    access_token = db.StringProperty()
    refresh_token = db.StringProperty()
    expire_date = db.DateTimeProperty()

class OAuthCode(webapp.RequestHandler):
    '''
    The step 1 of Getting an access token, 
    asks the user for permission to access their data
    http://code.google.com/apis/accounts/docs/OAuth2.html
    '''
    
    @login_required
    def get(self):
        '''
        Redirect your users to https://accounts.google.com/o/oauth2/auth
        to get code
        '''
        authorize_url = code_uri
        query = {
            'response_type': 'code',
            'client_id': client_id,
            'redirect_uri': redirect_uri,
            'scope': scope,
            }
        authorize_url = authorize_url + '?' + urllib.urlencode(query)
        self.redirect(authorize_url)
        
class OAuthToken(webapp.RequestHandler):
    '''
    The step 2 of Getting an access token, 
    Exhanges a code for access token and refresh token
    http://code.google.com/apis/accounts/docs/OAuth2.html
    '''
    
    @login_required
    def get(self):
        '''
        Redirect your users to https://accounts.google.com/o/oauth2/token
        to get token
        '''
        
        user = users.get_current_user()
        if self.request.get('error')!= '':
            self.response.out.write(self.request.get('error'))
            return
        
        body = urllib.urlencode({
            'grant_type': 'authorization_code',
            'client_id': client_id,
            'client_secret': client_secret,
            'code': self.request.get('code'),
            'redirect_uri': redirect_uri,
            'scope': scope
            })
        headers = {
            'content-type': 'application/x-www-form-urlencoded'
        }

        conn = httplib.HTTPSConnection(token_uri)
        conn.request('POST', token_uri, body=body, headers=headers)
        r1 = conn.getresponse()
        if r1.status == 200:
            d = json.loads(r1.read())
            access_token = d['access_token']
            refresh_token = d.get('refresh_token', None)
            token_expiry = None
            if 'expires_in' in d:
                token_expiry = datetime.datetime.now() + datetime.timedelta(seconds = int(d['expires_in']))

            credential = Credentials()
            credential.user = user
            credential.access_token = access_token
            credential.refresh_token = refresh_token
            credential.expire_date = token_expiry
            credential.put()
            logging.debug('save credential %s, %s', user.nickname(), token_expiry)
            if self.request.get('email'):
                param = urllib.urlencode({
                    'email': user.email()
                })
                self.redirect("/ical/?"+param)
            else:
                self.redirect("/")
        else:
            error_msg = 'Invalid response %s.' % r1.status
            self.response.out.write(error_msg)
            
class OAuthUpdate(webapp.RequestHandler):
    '''
    Update credential, 
    Get access token by refresh token
    http://code.google.com/apis/accounts/docs/OAuth2.html
    '''
    
    @login_required
    def get(self):
    
        user = users.get_current_user()
        credential = Credentials.gql("WHERE user = :user", user=user).get()
        
        if not credential:
            self.response.out.write('No credential to be updated')
            return
    
        body = urllib.urlencode({
            'grant_type': 'refresh_token',
            'client_id': client_id,
            'client_secret': client_secret,
            'refresh_token': credential.refresh_token,
            })
        headers = {
            'content-type': 'application/x-www-form-urlencoded'
        }
        
        logging.debug('refresh_token %s', credential.refresh_token)

        conn = httplib.HTTPSConnection(token_uri)
        conn.request('POST', token_uri, body=body, headers=headers)
        r1 = conn.getresponse()
        if r1.status == 200:
            d = json.loads(r1.read())
            access_token = d['access_token']
            refresh_token = d.get('refresh_token', credential.refresh_token)
            token_expiry = None
            if 'expires_in' in d:
                token_expiry = datetime.datetime.now() + datetime.timedelta(seconds = int(d['expires_in']))

            credential.user = user
            credential.access_token = access_token
            credential.refresh_token = refresh_token
            credential.expire_date = token_expiry
            credential.put()
            
            logging.debug('%s\n%s\n%s' ,credential.access_token, credential.refresh_token, r1.read())
            
            self.redirect("/")
        else:
            error_msg = 'Invalid response %s.' % r1.status
            self.response.out.write(error_msg)